package cn.maidouya.hrm.service.impl;

import cn.maidouya.hrm.constant.SmsConstant;
import cn.maidouya.hrm.domain.VipUser;
import cn.maidouya.hrm.dto.SmsDto;
import cn.maidouya.hrm.mapper.VipUserMapper;
import cn.maidouya.hrm.service.IImageCodeControllerServer;
import cn.maidouya.hrm.util.AjaxResult;
import cn.maidouya.hrm.util.ValidUtils;
import cn.maidouya.hrm.util.VerifyCodeUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.stereotype.Service;
import sun.misc.BASE64Encoder;

import javax.validation.Valid;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.concurrent.TimeUnit;

@Service
public class ImageCodeControllerServerImpl implements IImageCodeControllerServer {
    // redis方法
    @Autowired
    private RedisTemplate redisTemplate;
    @Autowired
    private VipUserMapper vipUserMapper;
    // 图片验证码
    @Override
    public AjaxResult getImageCodeKey(String imageCodeKey) throws IOException {
        // 1. 较空
        ValidUtils.assertNotNull(imageCodeKey,"获取验证码失败！");
        // 2. 生成验证为4位数
        String code = VerifyCodeUtils.generateVerifyCode(4);
        // 3. 验证码绑定到Redis中  做注册时校验
        redisTemplate.opsForValue().set(imageCodeKey,code,5, TimeUnit.MINUTES);
        // 将缓冲区的数据全部获取出来，并赋值给字节数组输出流。该方法可以通过 String 的方法
        // 使用指定的字符集，通过解码字节将缓冲区内容转换为字符串
        // 4. 创建byte字节对象数据
        ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();
        // 5. 调用outputImage方法把验证码转化为 100*40图片并使用byteArrayOutputStream输出图片字节byte文件存储
        VerifyCodeUtils.outputImage(100,40,byteArrayOutputStream,code);
        // 6.  创建base6规定的，转化为字节64字节字符串
        BASE64Encoder encoder = new BASE64Encoder();
        // 7. 调用encode方法验证转化为base64字符串
        String encode = encoder.encode(byteArrayOutputStream.toByteArray());
        // 8. 封装code图片给到前端页面渲染
        return AjaxResult.me().setResultObj(encode);
    }
    // 手机短信验证码
    @Override
    public AjaxResult sendSmsCode(@Valid SmsDto smsDto) {
        VipUser vipUser = new VipUser();
        vipUser.setPhone(smsDto.getMobile());
        vipUser = vipUserMapper.selectOne(vipUser);
        if (vipUser != null){
            throw new RuntimeException("该手机号码已注册！");
        }
        Object oldCode = redisTemplate.opsForValue().get(smsDto.getImageCodeKey());
        if (oldCode == null){
            throw new RuntimeException("图片验证码不存在，请重新获取！");
        }
        if (!oldCode.toString().toLowerCase().equals(smsDto.getImageCode().toLowerCase())){
            throw new RuntimeException("图片验证码不一致！");
        }

        Object codeObj = redisTemplate.opsForValue().get(SmsConstant.PHONE_SMS_CODE + smsDto.getMobile());
        String code;
        if (codeObj != null){
            String codeoObj = (String) codeObj;
            Long time = Long.valueOf(codeoObj.split(":")[1]);
            Long interval =System.currentTimeMillis() - time;

            if (interval <= 60 *60*100){
                throw new RuntimeException("请勿重发手机验证码！");
            }
            code = codeoObj.split(":")[0];
        }else {
            code = VerifyCodeUtils.generateVerifyCode(4, "123456789");
        }


        //String phoneCode = VerifyCodeUtils.generateVerifyCode(4, "123456789");

        // 注意时间戳使用  业务类型+手机号码 和 验证码+时间戳
        // redisTemplate.opsForValue().set(SmsConstant.PHONE_SMS_CODE+smsDto.getMobile(),phoneCode,5,TimeUnit.MINUTES);
        redisTemplate.opsForValue().set(SmsConstant.PHONE_SMS_CODE+smsDto.getMobile(),
                code+":"+System.currentTimeMillis(),
                1,TimeUnit.MINUTES);



        System.out.println("您的验证码："+code+ " 请在1分钟内使用！");



        return AjaxResult.me();
    }


}
